Improve frame interpolation#4919
Conversation
as this code is now reached before the current turn is subtracted
Makes the mouse light a little less flickery.
Clean up this function and match logic with get_player_coords_and_context() in front_input.c. Fixes local mouse light glitching when: - something is held in hand, and there is something under it to pick up - pointing just above/behind a door (DoorKey cursor state)
|
To reiterate, this is stuck because it doesn't play nice with 0-turns input lag in multiplayer. Or maybe, exposes existing problems with it, which the current interpolation method is better able to hide :) Video frames now must be drawn with Then however, another problem becomes apparent, which is that the client clock drifts. This causes the perceived latency to increase, and so it spends more time waiting and drawing stale frames. The reason is that clock sync (speed adjustment) depends on the round-trip timing measured by the ENet library, but this is inaccurate, because network messages are only sent and received once per turn. So the measured RTT is the sum of:
To solve this, I think network packets need to be answered in real-time, on a separate thread. I expect this involves some large restructuring that I'd rather not jump into, right now. Alternatively, maybe some other way of turn synchronizing can be found that doesn't rely on RTT at all. Eg. clients could adjust their clock based on when they receive a packet from the host. |
no (significant) functional changes
Because turn_phase_ns could now go negative with input_lag_turns == 0. It has no real effect though since this code isn't used then.
To get rid of the forward declaration.
| if (is_feature_on(Ft_DeltaTime)) | ||
| { | ||
| frametime_start_measurement(Frametime_Sleep); | ||
| if (turns_per_second_draw_current > 0) | ||
| keeper_wait_for_next_draw(); | ||
| frametime_end_measurement(Frametime_Sleep); | ||
| } |
There was a problem hiding this comment.
Here I moved the fps limiter to gameplay_loop_draw(). But now I think it could interfere with multiplayer timing here. On the other hand, if the limiter is only active in the normal gameplay loop but not during packet exchange, then average_delta_time becomes useless. May need to think some more about this.
The frame interpolation method used is non-linear and includes some future-prediction, which causes overshoots. #4908 works around the visual effect, but I believe it is better to use a purely linear method instead.
This did uncover some new bugs, where the previous-frame position was reset too early. Those have been fixed now.
I removed the minimap interpolation code, as it was not necessary. Both the (local) camera and all Things already have interpolated map positions, there is no need to do it twice.